/**
 * 克隆对象
 * obj：被克隆对象
 */
function clone<T>(obj: T): T {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }
  let copyObj: any = undefined;
  if (obj instanceof Date) {
    copyObj = new Date();
    copyObj.setTime(obj.getTime());
    return copyObj;
  }
  if (obj instanceof Array) {
    copyObj = [];
    for (let i = 0; i < obj.length; i++) {
      copyObj[i] = clone(obj[i]);
    }
    return copyObj;
  }
  if (obj instanceof Object) {
    copyObj = {};
    for (let attr in obj) {
      copyObj[attr] = clone(obj[attr]);
    }
    return copyObj;
  }
  return copyObj;
}
/**
 * 生成GUID
 * showLine：是否显示线条，默认不显示
 */
const guid = (showLine?: boolean) => {
  let guid = "";
  for (let i = 1; i <= 32; i++) {
    let n = Math.floor(Math.random() * 16.0).toString(16);
    guid += n;
    if (showLine) {
      if (i === 8 || i === 12 || i === 16 || i === 20) {
        guid += "-";
      }
    }
  }
  return guid;
};
/**
 * 判断浏览器类型，PC返回true，移动端返回false
 */
const isPc = () => {
  let userAgentInfo = navigator.userAgent;
  let agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
  let flag = true;
  for (let v = 0; v < agents.length; v++) {
    if (userAgentInfo.indexOf(agents[v]) > 0) {
      flag = false;
      break;
    }
  }
  return flag;
};

/**
 * 存储/读取localStorage数据
 * name: localStorage的key
 * value: localStorage的value
 */
const storage = (name: string, value?: any) => {
  if (!localStorage) {
    return "";
  }
  if (value !== undefined) {
    localStorage.setItem(name, JSON.stringify(value));
  } else {
    let value = localStorage.getItem(name);
    if (value) {
      return JSON.parse(value);
    }
    return;
  }
};

/**
 * 存储/读取sessionStorage数据
 * name: localStorage的key
 * value: localStorage的value
 */
const session = (name: string, value?: any) => {
  if (!sessionStorage) {
    return;
  }
  if (value !== undefined) {
    sessionStorage.setItem(name, JSON.stringify(value));
  } else {
    let value = sessionStorage.getItem(name);
    if (value) {
      return JSON.parse(value);
    }
    return;
  }
};

/**
 * fixStylePX
 * name: px
 * value: convertPX
 */
const fixStylePX = (px: any, convertPX: Function) => {
  if (!px) {
    return;
  }
  if (px.includes("%") || px === "auto") {
    return px;
  }
  return convertPX(px.replace("px", "")) + "px";
};
/**
 * 检查地址是否可以访问
 * @param serverUrl
 */
const checkServer = (serverUrl: string, callback: Function) => {
  var img = new Image();
  var start = new Date().getTime();
  var isReturn = false;
  img.src = `${serverUrl}/image/logo.png`;
  img.onload = function () {
    isReturn = true;
    var elapsed = new Date().getTime() - start;
    console.log(`Ping：${serverUrl} ${elapsed}ms`);
    callback(true);
  };
  img.onerror = function () {
    if (!isReturn) {
      console.log(`Ping：${serverUrl} 失败`);
      callback(false);
    }
  };
  setTimeout(() => {
    if (!isReturn) {
      isReturn = true;
      console.log(`Ping：${serverUrl} 失败`);
      callback(false);
    }
  }, 200);
};
/**
 * @description: 等待结束后再执行
 * @param time 等待时间，单位毫秒
 * @return
 */
const wait = (time: number) => {
  return new Promise((resolve) => setTimeout(resolve, time));
};

/**
 * @description: 深冻结对象
 * @param object 要冻结的对象
 * @return
 */
const deepFreeze = <T extends Record<string, any>>(object: T): T => {
  // 首先冻结第一层的属性
  Object.freeze(object);

  // 对象的每个属性，如果是对象类型的话，递归地冻结
  Object.getOwnPropertyNames(object).forEach((prop) => {
    if (
      object.hasOwnProperty(prop) &&
      object[prop] !== null &&
      (typeof object[prop] === "object" || typeof object[prop] === "function") &&
      !Object.isFrozen(object[prop])
    ) {
      deepFreeze(object[prop]);
    }
  });
  return object;
};

const hexToRgb = (hex: string): [number, number, number] => {
  // 去掉前面的 #
  hex = hex.replace(/^#/, "");

  // 解析 RGB 值
  const bigint = parseInt(hex, 16);
  const r = (bigint >> 16) & 255;
  const g = (bigint >> 8) & 255;
  const b = bigint & 255;

  return [r, g, b];
};

const rgbToHex = (r: number, g: number, b: number): string => {
  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
};
/**
 * @description: 颜色亮度调整
 * @param hex
 * @param percentage
 * @return
 */
const adjustBrightness = (hex: string, percentage: number): string => {
  if (!hex) {
    return "";
  }
  const [r, g, b] = hexToRgb(hex);

  // 计算新的 RGB 值
  const adjust = (value: number, percentage: number) => {
    const amount = (percentage / 100) * 255; // 计算调整值
    return Math.round(Math.min(255, Math.max(0, value + amount))); // 确保在 0 到 255 之间并四舍五入
  };

  const newR = adjust(r, percentage);
  const newG = adjust(g, percentage);
  const newB = adjust(b, percentage);

  return rgbToHex(newR, newG, newB);
};
/**
 * @description: 颜色亮度调整
 * @param hex
 * @param opacity
 * @return
 */
const adjustOpacity = (hex: string, opacity: number): string => {
  if (!hex) {
    return "";
  }

  // 确保透明度在 0 到 1 之间
  opacity = Math.min(1, Math.max(0, opacity));

  const [r, g, b] = hexToRgb(hex);

  // 返回 RGBA 字符串
  return `rgba(${r}, ${g}, ${b}, ${opacity})`;
};
/**
 * @description: 格式化数据
 * @param result
 * @param isFormatKeyArr
 * @return
 */
const resultFormat = (result: any, isFormatKeyArr: ResultFormatView): any => {
  // 检查对象的类型
  if (Array.isArray(result)) {
    // 如果是数组，递归处理每个元素
    return result.map((item) => resultFormat(item, isFormatKeyArr));
  } else if (result !== null && typeof result === "object") {
    // 如果是对象，遍历每个键
    for (const key in result) {
      if (typeof result[key] === "string") {
        let formatString = ""; // 初始化格式字符串
        if ((isFormatKeyArr.dateTime ?? []).includes(key)) {
          formatString = "YYYY-MM-DD HH:mm";
        } else if ((isFormatKeyArr.date ?? []).includes(key)) {
          formatString = "YYYY-MM-DD";
        } else if ((isFormatKeyArr.time ?? []).includes(key)) {
          formatString = "HH:mm";
        }
        // 只有在 formatString 有效时才进行格式化
        if (formatString) {
          const dateValue = dayjs(result[key]);
          if (dateValue.isValid()) {
            result[key] = dateValue.format(formatString);
          } else {
            console.warn(`Invalid date for key "${key}": ${result[key]}`);
            result[key] = result[key]; // 保持原值
          }
        }
        continue;
      }
      // 递归处理嵌套对象
      result[key] = resultFormat(result[key], isFormatKeyArr);
    }
  }
  return result;
};

/**
 * description: 地址参数转化为对象
 * param {string} url
 * param {*} string
 * return {*}
 */
const parseQueryParams = (url: string): Record<string, string | boolean> => {
  // 创建 URL 对象
  const urlObj = new URL(url);

  // 获取查询参数
  const params = new URLSearchParams(urlObj.search);

  // 创建一个空对象来存储参数
  const queryParams: Record<string, string | boolean> = {};

  // 遍历所有查询参数并添加到对象中
  params.forEach((value, key) => {
    // 尝试将参数值转换为布尔值或保留为字符串
    queryParams[key] = value === "true" ? true : value === "false" ? false : value;
  });

  return queryParams;
};

export default {
  clone,
  guid,
  isPc,
  storage,
  session,
  fixStylePX,
  checkServer,
  wait,
  deepFreeze,
  adjustBrightness,
  resultFormat,
  adjustOpacity,
  parseQueryParams
};
